package org.ponly.uno4j.util;

import org.ponly.common.proc.ProcHandler;
import org.ponly.common.proc.ProcStarter;
import org.ponly.common.proc.ProcTask;
import org.ponly.common.util.LazyValue;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Map;

/**
 * SWFTools - PDF2SWF
 * 注: 多个 pdf2swf 进程不能同时读取同一个 pdf 文件
 *
 * @author vacoor
 */
public class P2s extends ProcStarter {
    private String stHome;
    private String password;
    private boolean verbose;
    private boolean compression;
    private int jpegQuality;
    private Map<String, String> params;
    private boolean sameWindow;
    private boolean stop;
    private int flashVersion = 9;
    private String fontDir;
    private String defaultViewer;
    private String defaultLoader;
    private String viewer;
    private String preloader;
    private boolean quiet;
    private boolean shapes;
    private boolean fonts;
    private boolean flatten;
    private boolean info;
    private boolean maxtime;

    protected P2s() {
        super();
    }

    public static P2s create() {
        return new P2s();
    }

    public int execute(String input, String output, int... pages) throws IOException, InterruptedException {
        return super.execute(buildCommands(input, output, pages));
    }

    public ProcTask submit(String input, String output, int... pages) throws IOException {
        return super.submit(buildCommands(input, output, pages));
    }

    public ProcTask newTask(String input, String output, int... pages) {
        return super.newTask(buildCommands(input, output, pages));
    }

    @Override
    protected ProcHandler newHandler() {
        return super.newHandler();
    }

    protected String[] buildCommands(String input, String output, int... pages) {
        String[] commands = new String[]{
                "pdf2swf",
                "-T", "" + flashVersion,
                "-t",
                "-q",
                "-f",
                "-s", "linknameurl",
                "-s", "storeallcharacters",
                // "-v",
                // "", "",
                "-o", output,
                input
        };

        if (null == stHome) {
            stHome = SWF_TOOLS_HOME.getValue();
        }
        if (null != stHome) {
            // stHome 不为空时确保以 "/" 结尾
            String path = (stHome.isEmpty() || stHome.endsWith("/")) ? stHome : stHome + "/";
            commands[0] = path + commands[0];
        }

        if (null != pages && 0 < pages.length) {
            StringBuilder buff = new StringBuilder();
            for (int i = 0; i < pages.length; i++) {
                buff.append(pages[i]);
                if (0 < i) {
                    buff.append(",");
                }
            }
            commands[commands.length - 5] = "-p";
            commands[commands.length - 4] = buff.toString();
        }
        return commands;
    }

    public P2s setVerbose(boolean verbose) {
        this.verbose = verbose;
        return this;
    }

    public P2s setFlashVersion(int flashVersion) {
        this.flashVersion = flashVersion;
        return this;
    }

    // PDF 相关参数
    public static final String PARAM_PDF_FONTDIR = "fontdir";
    public static final String PARAM_PDF_FONT = "font";
    public static final String PARAM_PAGES = "pages";
    public static final String PARAM_PDF_ZOOM = "zoom";
    public static final String PARAM_PDF_LANGUAGEDIR = "languagedir";
    public static final String PARAM_PDF_MULTIPLY = "multiply";
    public static final String PARAM_PDF_POLY2BITMAP = "poly2bitmap";
    public static final String PARAM_PDF_BITMAP = "bitmap";

    // SWF 相关参数
    public static final String PARAM_SWF_JPEGSUBPIXELS = "jpegsubpixels";
    public static final String PARAM_SWF_PPMSUBPIXELS = "ppmsubpixels";
    public static final String PARAM_SWF_SUBPIXELS = "subpixels";
    public static final String PARAM_SWF_DRAW_ONLY_SHAPES = "drawonlyshapes";
    public static final String PARAM_SWF_IGNORE_DRAW_ORDER = "ignoredraworder";
    public static final String PARAM_SWF_LINKS_OPEN_NEW_WINDOW = "linksopennewwindow";
    public static final String PARAM_SWF_LINK_TARGET = "linktarget";
    public static final String PARAM_SWF_LINK_COLOR = "LINKCOLOR";
    public static final String PARAM_SWF_LINK_NAME_URL = "linknameurl";
    public static final String PARAM_SWF_STORE_ALL_CHARACTERS = "storeallcharacters";
    public static final String PARAM_SWF_ENABLE_ZLIB = "enablezlib";
    public static final String PARAM_SWF_BBOX_VARS = "bboxvars";
    public static final String PARAM_SWF_DOTS = "dots";
    public static final String PARAM_SWF_REORDER_TAGS = "reordertags";
    public static final String PARAM_SWF_INTERNAL_LINK_FUNCTION = "internallinkfunction";
    public static final String PARAM_SWF_EXTERNAL_LINK_FUNCTION = "externallinkfunction";
    public static final String PARAM_SWF_DISABLE_POLYGON_CONVERSION = "disable_polygon_conversion";
    public static final String PARAM_SWF_CAPLINE_WIDTH = "caplinewidth";
    public static final String PARAM_SWF_INSERT_STOP = "insertstop";
    public static final String PARAM_SWF_PROTECT = "protect";
    public static final String PARAM_SWF_FLASH_VERSION = "flashversion";
    public static final String PARAM_SWF_FRAME_RATE = "framerate";
    public static final String PARAM_SWF_MIN_LINE_WIDTH = "minlinewidth";
    public static final String PARAM_SWF_SIMPLE_VIEWER = "simpleviewer";
    public static final String PARAM_SWF_ANIMATE = "animate";
    public static final String PARAM_SWF_JPEG_QUALITY = "jpegquality";
    public static final String PARAM_SWF_SPLINE_QUALITY = "splinequality";
    public static final String PARAM_SWF_DISABLE_LINKS = "disablelinks";

    private static final LazyValue<String> SWF_TOOLS_HOME = new LazyValue<String>() {
        @Override
        protected String compute() {
            String stHome = System.getProperty("swftools.home");

            if (null != stHome) {
                stHome = System.getenv("SWFTOOLS_HOME");
            }
            if (null == stHome) {
                if (UnoUtils.WINDOWS) {
                    stHome = findStHome(System.getenv("ProgramFiles"), System.getenv("ProgramFiles(x86)"));
                }
            }
            return stHome;
        }

        private String findStHome(String... paths) {
            if (0 == paths.length) {
                return null;
            }
            for (String path : paths) {
                if (null == path || 0 == path.length()) {
                    continue;
                }
                File[] files = new File(path).listFiles(new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        return name.equalsIgnoreCase("SWFTools");
                    }
                });
                if (null != files && 0 < files.length) {
                    return files[0].getAbsolutePath().replace("\\", "/");
                }
            }
            return null;
        }
    };
}
